# coding=utf-8

from flask import Flask, render_template, session, g, request
from flask.ext.mail import Mail
from flask.ext.sqlalchemy import SQLAlchemy
from redis import Redis
from uzwan import config
from uzwan.consts import C_CHANNEL
from uzwan.lib import get_cookie
from uzwan.lib.cache_region import CacheRegion
from uzwan.lib.redis_session import RedisSessionInterface

mail = Mail()
db = SQLAlchemy()
redis = Redis(host=config.REDIS_HOST, port=config.REDIS_PORT)
cache = CacheRegion(redis)

#-- create flask app --
def create_app():
    app = Flask(__name__)
    configure_logging(app)

    app.logger.info('Setting up uzwan application...')
    app.config.from_object(config)

    configure_exts(app)
    configure_err_handlers(app)
    configure_blueprints(app)
    configure_request_processors(app)

    app.session_interface = RedisSessionInterface(redis)

    return app

def configure_exts(app):
    app.logger.info('Configure extensions(db, mail)...')
    db.init_app(app)
    mail.init_app(app)

#-- register request filters --
def configure_request_processors(app):
    app.logger.info('Configure request processors...')
    from uzwan.models.channel import Channel
    from uzwan.models.account import not_login_user
    # 事务处理
    @app.teardown_request
    def process_transaction(exception=None):
        if exception:
            db.session.rollback()
            db.session.remove()
            return
        try:
            db.session.commit()
        except:
            db.session.rollback()
        finally:
            db.session.remove()

    @app.before_request
    def get_user():
        g.user = session.get('user', not_login_user)


    @app.before_request
    def get_channel():
        g.channel = get_cookie(request, C_CHANNEL) or Channel.get_self_channel().id

#-- register err handlers --
def configure_err_handlers(app):
    app.logger.info('Configure error handlers...')

    @app.errorhandler(400)
    def bad_request(error):
        d = {'title': u'错误请求', 'message': u'缺少必要参数，或参数格式错误'}
        return render_template('error.html', **d), 400

    @app.errorhandler(403)
    def forbidden(error):
        d = {'title': u'您没有权限', 'message': u'您没有权限执行当前操作，请登录或检查url是否错误'}
        return render_template('error.html', **d), 403

    @app.errorhandler(404)
    def page_not_found(error):
        d = {'title': u'页面不存在', 'message': u'您访问的页面不存在，请检查url是否错误'}
        return render_template('error.html', **d), 404

    @app.errorhandler(500)
    def server_error(error):
        d = {'title': u'页面出错了', 'message': u'您访问的页面出错了，我们正在加紧修复中...'}
        return render_template('error.html', **d), 500

def configure_blueprints(app):
    app.logger.info('Configure blueprints...')
    from uzwan.views import account, home, game, api

    app.register_blueprint(home.blueprint, url_prefix='')
    app.register_blueprint(account.blueprint, url_prefix='/account')
    app.register_blueprint(game.blueprint, url_prefix='/game')
    app.register_blueprint(api.blueprint, url_prefix='/api')

def configure_logging(app):
    app.debug_log_format = '[%(levelname)s] %(message)s'
    app.debug = True